<template>
  <view v-if="!isLoading" class="container" :style="appThemeStyle">
    <view class="header-wrap">
      <view class="status-title">
        <text class="title" @click="handleTracks">
          <text v-if="order.orderStatus">{{ OrderStatusEnum.data.find(val => val.value === order.orderStatus)?.name }}</text>
          <text v-else>{{ RefundStatusEnum.data.find(val => val.value === order.refundStatus)?.name }}</text>
          <text class="iconfont icon-arrow-right"></text>
        </text>
      </view>
      <view
        v-if="predictPickCompletedTime &&
        (order.orderStatus === OrderStatusEnum.NEW.value ||
         order.orderStatus === OrderStatusEnum.RECEIVES.value ||
         order.orderStatus === OrderStatusEnum.REVIEWED.value)"
        class="tips"
        :class="{active: formatDiffTime(predictPickCompletedTime).includes('剩余')}"
      >
        拣货{{ formatDiffTime(predictPickCompletedTime) }}
      </view>
    </view>
    <view class="card-wrap">
      <view class="user">
        <view class="user__left">
          <text class="name">{{ order.clientName || '' }}</text>
          <text class="tag">客户</text>
        </view>
        <view class="user__right" @click="handlePhone(order.clientPhone)">
          <text class="iconfont phone">&#xe6bd;</text>
          <text class="call">联系客户</text>
        </view>
      </view>
      <view class="tel">{{ order.clientPhone }}</view>
      <view class="address">
        {{ order.clientAddress || '地址：无' }}
      </view>
    </view>
    <view class="card-wrap" v-if="order.clientRemarks">
      <view class="tips-wrap">
        <view class="area">
          <text class="iconfont">&#xe6c9;</text>
          <text class="text">备注：</text>
        </view>
        <view class="client-remark">{{ order.clientRemarks }}</view>
      </view>
    </view>
    <view class="card-wrap" v-if="orderGoods">
      <view class="card-title">商品信息</view>
      <view class="goods-list">
        <view class="goods-item" v-for="(item, index) in orderGoods" :key="index">
          <view class="item-flex">
            <view class="image-wrap">
              <image :src="item.primaryPicUrl"/>
            </view>
            <view class="good-info">
              <view class="title-wrap">
                <text class="name oneline-hide">{{ item.goodsName || item.name}}</text>
                <text>¥ {{ item.sellPrice || item.refundPrice  }}</text>
              </view>
              <view class="describe">
                <text>编码：{{ item.skuCode || '' }}</text>
                <text class="through" v-if="item.sellPrice && item.originalPrice > item.sellPrice">¥{{ item.originalPrice }}</text>
                <text class="through" v-if="item.refundPrice && item.originalPrice > item.refundPrice">¥{{ item.originalPrice }}</text>
              </view>
              <view class="describe">条码：{{ item.barcode || '' }}</view>
              <view class="describe">
                <text>重量：{{ item.weight || 0 }}g</text>
                <text :class="['ele', {active: item.quantity > 1 }]">x {{ item.quantity || '' }}</text>
              </view>
              <view class="describe" v-if="item.featureRemark">
                <text>{{ item.featureRemark }}</text>
              </view>
              <view class="goods-tips" v-if="item.refundStatus === RefundStatusEnum.REFUNDED.value && item.refundQuantity">
                <text class="tips-icon">!</text>
                <text class="tips-text">{{ item.refundQuantity < item.quantity ? '部分退' : '已退款' }}</text>
                <text class="tips-refund-text">共退：{{ item.refundQuantity || '' }}件</text>
                <text class="tips-top" />
              </view>
            </view>
          </view>
        </view>
      </view>
      <view class="cell-group">
        <view class="cell-item">
          <view class="label">商品总价</view>
          <view class="value">¥ {{ order.goodsAmount || 0 }}</view>
        </view>
        <view class="cell-item">
          <view class="label">配送费</view>
          <view class="value">¥ {{ order.deliveryAmount || 0 }}</view>
        </view>
        <view class="cell-item">
          <view class="label">包装费</view>
          <view class="value">¥ {{ order.packageAmount || 0 }}</view>
        </view>
        <view class="cell-item">
          <view class="label">优惠金额</view>
          <view class="value active">-¥ {{ order.discountAmount || 0 }}</view>
        </view>
        <view class="cell-total">
          <text class="m-left">共{{ order.goodsCount || 0 }}件商品</text>
          <text class="m-right">
            <text>{{ order.refundOrderId ? '退款' : '实付' }}金额：</text>
            <text>
              <text class="font">¥</text>
              <text class="m-price price-icon">{{ order.payAmount || order.refundAmount }}</text>
            </text>
          </text>
        </view>
      </view>
    </view>
    <view class="card-wrap">
      <view class="card-title">订单信息</view>
      <view class="cell-group">
        <view class="cell-item">
          <view class="label">{{ order.orderStatus ? '订单号' : '退单号'}}</view>
          <view class="value">
            <text>{{ order.orderStatus ? order.channelOrderNo : order.channelRefundOrderNo }}</text>
            <text class="iconfont m-l-10" @click="copyNumber(order.orderStatus ? order.channelOrderNo : order.channelRefundOrderNo)">&#xe6cb;</text>
          </view>
        </view>
        <view class="cell-item" v-if="order.refundStatus">
          <view class="label">关联订单号</view>
          <view class="value">{{ order.channelOrderNo }}</view>
        </view>
        <view class="cell-item">
          <view class="label">下单时间</view>
          <view class="value">{{ order.createTime || '--' }}</view>
        </view>
        <view class="cell-item" v-if="predictPickCompletedTime">
          <view class="label">预计拣货完成时间</view>
          <view class="value">{{ formatTime(predictPickCompletedTime) }}</view>
        </view>
        <view class="cell-item" v-if="order.expectedDeliveryEndTime">
          <view class="label">预计送达时间</view>
          <view class="value">{{ formatTime(order.expectedDeliveryEndTime) }}</view>
        </view>
        <view class="cell-item">
          <view class="label">订单渠道</view>
          <view class="value">{{ channels.find(val => val.thirdChannelId === order.thirdChannelId)?.channelName || '--' }}</view>
        </view>
        <view class="cell-item">
          <view class="label">订单重量</view>
          <view class="value"> {{ order.goodsWeight || 0 }}g</view>
        </view>
        <view class="cell-item">
          <view class="label">配送方式</view>
          <view class="value" v-if="order.channelDeliveryType">{{ ChannelDeliveryTypeEnum.data.find(val => val.value === order.channelDeliveryType)?.name || '--' }}</view>
          <text class="value" v-else>{{ PerformanceTypeEnum.data.find(val => val.value === order.performanceType)?.name || '--' }}</text>
        </view>
        <view class="cell-item">
          <view class="label">订单备注</view>
          <view class="value active">{{ order.remarks || '无' }}</view>
        </view>
      </view>
    </view>
    <!-- 底部操作按钮 -->
    <view class="footer-fixed">
      <view class="btn-wrapper">
        <u-button
          v-if="isCancel"
          :custom-style="customStyle"
          @click="$confirm(() => cancelOrder(), { content: '您是否确认取消订单？' })"
        >取消订单</u-button>
        <Permission code="ly_order_info_part_refund">
          <u-button
            type="primary"
            :custom-style="customStyle"
            v-if="isPartRefund"
            @click="handleShowPart"
          >部分退货</u-button>
        </Permission>
        <u-button
          type="primary"
          :custom-style="customStyle"
          v-if="getVerification"
          @click="$confirm(() => confirmVerify(), { content: '您是否确认自提核验？' })"
        >确认核验</u-button>
      </view>
    </view>

    <!--部分退限制退款提示-->
    <u-modal
      v-model="showPartModal"
      title="提示"
      :content="partModalText"
      confirm-text="我已知悉"
      :title-style="{
        fontWeight: 'bold'
      }"
      @confirm="showPartModal = false"
    >
    </u-modal>

    <!--部分退提交弹窗-->
    <PartPopup
      ref="partPopupRef"
      :order="order"
      @confirm="handlePartConfirm"
    />

    <!--订单轨迹-->
    <Tracks :list="tracks" ref="tracksRef"/>
  </view>
</template>

<script>
import store from '@/store'
import * as OrderApi from '@/api/order/order'
import * as RefundApi from '@/api/order/refund'
import Tracks from './components/tracks.vue'
import PartPopup from './components/part-popup.vue'
import OrderStatusEnum from "@/common/enum/order/orderStatus"
import RefundStatusEnum from "@/common/enum/order/refundStatus"
import ChannelTypeEnum from '@/common/enum/channelType'
import ChannelDeliveryTypeEnum from "@/common/enum/order/channelDeliveryType"
import PerformanceTypeEnum from "@/common/enum/order/performanceType"
import { diffTime, isEmpty, cloneObj } from "@/utils/util"
import StoreModel from '@/common/model/Store'

export default {
  name: "detail",
  components: { Tracks, PartPopup },
  data() {
    return {
      customStyle: {
        marginLeft: '16rpx',
        height: '64rpx',
        padding: '12rpx 24rpx'
      },
      isEmpty,
      OrderStatusEnum,
      RefundStatusEnum,
      ChannelTypeEnum,
      ChannelDeliveryTypeEnum,
      PerformanceTypeEnum,
      // 当前订单ID
      orderId: null,
      // 售后单id
      refundOrderId: null,
      verification: '',
      // 当前订单详情
      order: {},
      // 加载中
      isLoading: true,
      tracks: [],
      // 预计拣货完成时间(详情没返回，故从列表带过来)
      predictPickCompletedTime: '',
      showPartModal: false,
      partModalText: '',
      hasForce: false
    }
  },
  computed: {
    channels() {
      return store.getters.channels
    },
    isCancel() {
      if (this.verification) return false
      const { isReturn } = this.order
      return !!isReturn
    },
    isPartRefund() {
      if (this.verification) return false
      const { isPartReturn } = this.order
      return isPartReturn
    },
    getVerification () {
      return this.verification || this.order.verification
    },
    formatDiffTime() {
      return (val) => {
        return diffTime(val)
      }
    },
    formatTime() {
      return (val) => {
        return this.$moment(Number(val)).format("YYYY-MM-DD HH:mm")
      }
    },
    orderGoods() {
      const { orderGoods, goodsList } = this.order
      return orderGoods || goodsList
    }
  },
  onLoad({ orderId, refundOrderId, verification, order, predictPickCompletedTime }) {
    if (predictPickCompletedTime) this.predictPickCompletedTime = predictPickCompletedTime
    if (order) {
      this.order = JSON.parse(order)
      this.orderId = this.order.orderId
      this.isLoading = false
      return
    }
    this.orderId = orderId
    this.refundOrderId = refundOrderId
    this.verification = verification
    this.getOrderDetail()
  },
  methods: {
    async getOrderDetail() {
      this.isLoading = true
      const fetch = this.refundOrderId ? RefundApi.refundDetail : OrderApi.getOrderDetail
      const id = this.refundOrderId || this.orderId
      const { data } = await fetch(id)
      if (data) {
        this.order = data
        this.isLoading = false
        await this.getOrderDetailGoods(data)
      }
    },
    async getOrderDetailGoods(data) {
      const { thirdChannelId, channelOrderNo, orderGoods } = data
      if (thirdChannelId === ChannelTypeEnum.MT.value) {
        const { data: result } = await OrderApi.getOrderDetailGoods({ thirdChannelId, channelOrderNo })
        if (result) {
          orderGoods.forEach(item => {
            item.remainingRefundAmount = 0
            const tmp = result.goodsList.find(val => val.itemId === item.itemId)
            if (tmp) item.remainingRefundAmount = tmp.remainingRefundAmount
          })
          this.order = {
            ...data,
            orderGoods
          }
        }
      }
    },
    // 订单轨迹
    handleTracks() {
      const { refundOrderId, orderId } = this.order
      const fetch = refundOrderId ? RefundApi.getRefundOrderTracks : OrderApi.getOrderTracks
      const id = refundOrderId || orderId
      fetch(id, { load: false }).then(({ data }) => {
        this.tracks = data.reverse()
        this.$refs.tracksRef.show()
      })
    },
    handlePhone(phone) {
      if (!phone) return this.$toast('此订单信息不全，暂无法拨打电话')
      uni.makePhoneCall({
        phoneNumber: phone,
        success: () => {
          console.log("调用成功!")
        },
        fail: () => {
          console.log("调用失败!")
        }
      })
    },
    // 取消订单
    cancelOrder() {
      const {thirdChannelId, orderId, channelOrderNo} = this.order
      RefundApi.cancelOrder({
        thirdChannelId,
        orderId,
        channelOrderNo,
        force: this.hasForce
      }, { isPrompt: false }).then(() => {
        this.$success('操作完成')
        setTimeout(this.getOrderDetail, 1500)
        StoreModel.logs({
          status: 1,
          businessId: channelOrderNo,
          operationType: 'order_cancel'
        })
      }).catch(({code, msg}) => {
        if (code === 4000) {
          this.partModalText = msg
          this.showPartModal = true
          this.hasForce = true
        } else {
          this.$toast(msg)
        }
        StoreModel.logs({
          status: 0,
          businessId: channelOrderNo,
          operationType: 'order_cancel'
        })
      })
    },
    // 核验
    confirmVerify() {
      const { thirdChannelId, orderId, channelOrderNo, shopId } = this.order
      OrderApi.orderVerify({
        thirdChannelId,
        orderId,
        channelOrderNo,
        shopId,
        verification: this.getVerification,
        verifyCheck: false
      }).then(() => {
        this.$success('操作成功')
        setTimeout(() => {
          uni.navigateBack()
        }, 1500)
        StoreModel.logs({
          context: `自提码：${this.getVerification}`,
          status: 1,
          businessId: channelOrderNo,
          operationType: 'self_pick'
        })
      }).catch(() => {
        StoreModel.logs({
          context: `自提码：${this.getVerification}`,
          status: 0,
          businessId: channelOrderNo,
          operationType: 'self_pick'
        })
      })
    },
    handleShowPart() {
      this.$refs.partPopupRef.show()
    },
    // 部分退&&整单退
    handlePartConfirm(params) {
      const nParams = cloneObj(params)
      delete nParams.isRefundAll
      nParams.force = this.hasForce
      const { cancelOrder, partReturn } = RefundApi
      const requestFun = params.isRefundAll ? cancelOrder : partReturn
      requestFun(nParams, { isPrompt: false }).then(({ data }) => {
        if (data) {
          this.$success('操作完成')
          this.$refs.partPopupRef.hide()
          setTimeout(this.getOrderDetail, 1500)
          StoreModel.logs({
            status: 1,
            businessId: nParams.channelOrderNo,
            operationType: params.isRefundAll ? 'order_cancel' : 'part_refund'
          })
        }
      }).catch(({code, msg})=> {
        if (code === 4000) {
          this.partModalText = msg
          this.showPartModal = true
          this.hasForce = true
        } else {
          this.$toast(msg)
        }
        StoreModel.logs({
          status: 0,
          businessId: nParams.channelOrderNo,
          operationType: params.isRefundAll ? 'order_cancel' : 'part_refund'
        })
      })
    },
    // 复制单号
    copyNumber(id) {
      uni.setClipboardData({
        data: id,
        success: () => this.$toast('已复制'),
        fail: ({ errMsg }) => this.$toast('复制失败 ' + errMsg)
      })
    }
  }
}
</script>

<style scoped lang="scss">
.container {
  padding: 24rpx;
  // 设置ios刘海屏底部横线安全区域
  padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
  padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);

  .header-wrap {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .status-title {
      display: flex;
      align-items: center;
      font-size: 36rpx;

      .title {
        margin-right: 16rpx;
      }

      .iconfont {
        font-size: 40rpx;
      }
    }

    .tips {
      color: #F53F3F;

      &.active {
        color: #00B42A;
      }
    }
  }

  .card-wrap {
    padding: 24rpx;
    background: #fff;
    border-radius: 16rpx;
    margin-top: 16rpx;

    .card-title {
      font-size: 32rpx;
      font-weight: bold;
      margin-bottom: 10rpx;
    }

    .user {
      display: flex;
      align-items: center;
      justify-content: space-between;

      &__left {
        display: flex;
        align-items: center;

        .name {
          font-weight: bold;
          margin-right: 16rpx;
        }

        .tag {
          background: #F8F8F8;
          color: #666666;
          padding: 5rpx 10rpx;
          border-radius: 8rpx;
          font-size: 20rpx;
        }
      }

      &__right {
        display: flex;
        align-items: center;

        .call {
          margin-left: 16rpx;
        }
      }
    }

    .tel {
      margin: 20rpx 0;
      color: #666666;
    }

    .address {
      color: #666666;
    }

    .tips-wrap {
      display: flex;
      align-items: center;
      justify-content: space-between;

      .area {
        display: flex;
        align-items: center;

        .iconfont {
          color: #FF7D00;
        }

        .text {
          margin-left: 8rpx;
        }
      }

      .client-remark {
        width: 500rpx;
        text-align: right;
      }
    }

    .cell-group {

      .cell-item {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 20rpx 0;

        .label {
          color: #666;
        }

        .active {
          color: #F53F3F;
          width: 500rpx;
          text-align: right;
        }
      }

      .cell-total {
        text-align: right;
        background: #FAFAFA;
        padding: 16rpx 0;
        border-radius: 16rpx;

        .m-left {
          margin-right: 20rpx;
        }

        .m-right {
          font-weight: 500;

          .font {
            font-size: 24rpx;
          }

          .m-price {
            font-size: 32rpx;
            margin-left: 5rpx;
          }
        }
      }
    }

  }

  .goods-list {

    .goods-item {
      padding: 16rpx 0;

      .item-flex {
        display: flex;

        .item-radio {
          width: 50rpx;
          position: relative;

          .checkbox {
            position: absolute;
            top: 42%;
            transform: translate(0, -50%);
          }
        }

        .image-wrap {
          width: 128rpx;
          height: 128rpx;
          position: relative;

          image {
            width: 100%;
            height: 100%;
            border-radius: 4rpx;
          }
        }

        .good-info {
          flex: 1;
          margin-left: 16rpx;
          position: relative;

          .title-wrap {
            font-size: 28rpx;
            font-weight: 600;
            display: flex;
            justify-content: space-between;
            margin-bottom: 10rpx;

            .name {
              max-width: 400rpx;
            }
          }

          .describe {
            font-size: 24rpx;
            line-height: 42rpx;
            color: #999;
            display: flex;
            align-items: center;
            justify-content: space-between;

            .through {
              text-decoration: line-through;
            }

            .ele {
              font-weight: 500;
              color: #333;

              &.active {
                color: #F53F3F;
              }
            }
          }

          .goods-tips {
            font-size: 24rpx;
            display: flex;
            align-items: center;
            padding: 10rpx 16rpx;
            background: #fff1f1;
            border-radius: 8rpx;
            margin-top: 10rpx;
            position: relative;
            color: #ff4141;

            .tips-icon {
              width: 28rpx;
              height: 28rpx;
              border-radius: 50%;
              display: flex;
              align-items: center;
              justify-content: center;
              font-size: 22rpx;
              border: 1rpx solid #ff4141;
            }

            .tips-text {
              line-height: 28rpx;
              padding-left: 12rpx;
            }

            .tips-refund-text {
              margin-left: auto;
            }

            .tips-top {
              width: 16rpx;
              height: 16rpx;
              background: #fff1f1;
              transform: rotate(45deg);
              position: absolute;
              z-index: 1;
              top: -8rpx;
              right: 12rpx;
            }
          }
        }
      }

      .item-bottom {

        .input-wrap {
          width: 228rpx;
          margin: 0 20rpx;

          input {
            padding: 5rpx 20rpx;
            border: 1px solid #c8c9cc;
            border-radius: 8rpx;
          }
        }

        .part-money {
          display: flex;
          align-items: center;
          justify-content: space-around;
          font-size: 26rpx;

          .part-left {
            display: flex;
            align-items: center;
          }
        }

        .weight-item {
          display: flex;
          align-items: center;
          font-size: 26rpx;
          margin-bottom: 20rpx;
        }
      }
    }
  }

  // 底部操作栏
  .footer-fixed {
    position: fixed;
    bottom: var(--window-bottom);
    left: 0;
    right: 0;
    z-index: 11;
    background: #fff;
    border-top: 2rpx solid #eee;
    // 设置ios刘海屏底部横线安全区域
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);

    .btn-wrapper {
      padding: 16rpx 32rpx;
      display: flex;
      justify-content: flex-end;
      align-items: center;
    }
  }

  ::-webkit-scrollbar {
    width: 0;
    height: 0;
    color: transparent;
  }
}
</style>
